package org.admin.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import core.data.DataHandle;
import org.admin.entity.domain.App;
import org.admin.entity.domain.Menu;
import org.admin.entity.domain.Perms;
import org.admin.entity.dto.AppDto;
import org.admin.entity.vo.AppFetchVo;
import org.admin.entity.vo.AppQueryVo;
import org.admin.mapper.AppMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.*;

@Service
public class AppService {
    @Autowired
    AppMapper mapper;
    public void create(DataHandle<AppDto, ?> handle) {
        AppDto params = handle.getParams();
        LambdaQueryWrapper<App> query = new LambdaQueryWrapper<>();
        Date now = new Date();
        App app= new App();
        boolean doUpdate = true;

        if(params.getId() != null){
            // 验证数据
            if(mapper.selectCount(new LambdaQueryWrapper<App>().eq(App::getId, params.getId())) == 0){
                handle.failure("id", "指定应用不存在或已删除");
                return;
            }
            query.ne(App::getId, params.getId());
            app.setId(params.getId());
        }else{
            doUpdate = false;
            app.setCreatedAt(now);
        }
        query.eq(App::getModule, params.getModule());
        if(mapper.selectCount(query) > 0){
            handle.failure("module", "模块名称已经存在");
            return ;
        }

        app.setUpdatedAt(now);
        app.setName(params.getName());
        app.setDetail(params.getDetail());
        app.setModule(params.getModule());
        app.setPicture(params.getPicture());

        if(doUpdate) {
            mapper.updateById(app);
        }else{
            mapper.insert(app);
        }
        handle.success();
    }

    public void query(DataHandle<AppDto, IPage<AppQueryVo>> handle) {
        AppDto params = handle.getParams();
        MPJLambdaWrapper<App> query = new MPJLambdaWrapper<>();
        query//.distinct()
                .selectAll(App.class)
                // .select(App::getId)
                .selectFunc(() -> "COUNT(%s)", Perms::getId, AppQueryVo::getPermsCount)
                .selectFunc(() -> "COUNT(%s)", Menu::getId, AppQueryVo::getMenuCount)
                .leftJoin(Menu.class, Menu::getAppId, App::getId)
                .leftJoin(Perms.class, Perms::getAppId, App::getId)
                .orderByAsc(App::getSort)
                .groupBy(App::getId);
        if(params.getModule() != null){
            query.eq(App::getModule, params.getModule());
        }

        if(params.getName() != null){
            query.like(App::getName, "%" + params.getName() + "%");
        }

        IPage<AppQueryVo> appPage = mapper.selectJoinPage(
                new Page<>(params.getCurrent(), params.getSize()),
                AppQueryVo.class,
                query);

        handle.success(appPage);
    }

    public void fetch(DataHandle<AppDto, AppFetchVo> handle) {
        AppDto params = handle.getParams();
        App app = mapper.selectById(params.getId());
        if(app == null){
            handle.failure("id", "指定应用ID不存在");
            return;
        }
        handle.success(new AppFetchVo(app));
    }

    public void remove(DataHandle<AppDto, ?> handle) {
        AppDto params = handle.getParams();
        Set<Integer> idsSet = new HashSet<>(params.getIds());
        for(Map<String, Object> item: JoinWrappers.lambda(App.class)
                .select(App::getId, App::getName)
                .selectFunc(() -> "COUNT(%s)", Menu::getId, "menuCount")
                .leftJoin(Menu.class, Menu::getAppId, App::getId)
                .in(App::getId, params.getIds())
                .groupBy(App::getId)
                .list(HashMap.class)
                .stream()
                .map(item -> new HashMap<String, Object>(){{
                    put("id", item.get("id"));
                    put("name", item.get("name"));
                    put("menuCount", item.get("menuCount"));
                }}).toList()){
            if(item.get("menuCount") != null && (long) item.get("menuCount") > 0) {
                handle.failure(item.get("name") + ": 存在菜单，请删除后再试");
                return;
            }else{
                idsSet.remove((int) item.get("id"));
            }
        }

        if(!idsSet.isEmpty()){
            handle.failure("ids","指定了无效的应用");
            return;
        }
        // 查询 menu表

        mapper.deleteBatchIds(params.getIds());
        handle.success();
    }
}
